package com.weixing.mall.provider.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.weixing.mall.base.constant.GlobalConstant;
import com.weixing.mall.base.enums.SnCodeEnum;
import com.weixing.mall.base.exception.BusinessException;
import com.weixing.mall.base.orm.MPage;
import com.weixing.mall.base.wrapper.Result;
import com.weixing.mall.base.enums.WhetherEnum;
import com.weixing.mall.provider.api.model.query.ErpGoodsQuery;
import com.weixing.mall.provider.api.model.vo.ErpProductVo;
import com.weixing.mall.provider.api.model.vo.GoodsDetailsVo;
import com.weixing.mall.provider.api.model.vo.ItemVo;
import com.weixing.mall.provider.api.model.vo.ProductStockVo;
import com.weixing.mall.provider.api.model.vo.dto.RpcProductStockDto;
import com.weixing.mall.provider.api.service.GoodsFeign;
import com.weixing.mall.provider.api.service.ItemFeign;
import com.weixing.mall.provider.mapper.*;
import com.weixing.mall.provider.model.domain.Depot;
import com.weixing.mall.provider.model.domain.ProductStock;
import com.weixing.mall.provider.model.domain.ProductStockDetails;
import com.weixing.mall.provider.model.dto.*;
import com.weixing.mall.provider.model.enums.DepotTypeEunm;
import com.weixing.mall.provider.model.query.ProductStockExistQuery;
import com.weixing.mall.provider.model.query.ProductStockQuery;
import com.weixing.mall.provider.model.vo.*;
import com.weixing.mall.provider.service.*;
import com.weixing.mall.util.ListUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 仓库模块-商品库存表 服务实现类
 * </p>
 *
 * @author Small
 * @since 2019-11-15
 */
@Service
public class ProductStockServiceImpl extends ServiceImpl<ProductStockMapper, ProductStock> implements IProductStockService {

    @Autowired
    private GoodsTransBillMapper goodsTransBillMapper;
    @Autowired
    private GoodsTransBillProductMapper goodsTransBillProductMapper;
    @Autowired
    private InDepotBillMapper inDepotBillMapper;
    @Autowired
    private InDepotBillProductMapper inDepotBillProductMapper;
    @Autowired
    private OutDepotBillMapper outDepotBillMapper;
    @Autowired
    private OutDepotBillProductMapper outDepotBillProductMapper;
    @Autowired
    private IOutDepotBillService outDepotBillService;
    @Autowired
    private GoodsFeign goodsFeign;;
    @Autowired
    private ItemFeign itemFeign;
    @Autowired
    private IInDepotBillService inDepotBillService;
    @Autowired
    private IDepotService depotService;
    @Autowired
    private IProductStockDetailsService productStockDetailsService;

    @Override
    public IPage<ProductStockListVo> selectOfPage(Page page,ProductStockQuery productStockQuery) {
        //查询ERP仓ID
        Depot depot=depotService.getDepotByCode(GlobalConstant.DepotCode.ERP);
        if(ObjectUtil.isNotEmpty(productStockQuery)
                && ObjectUtil.isNotEmpty(depot)
                &&depot.getId().equals(productStockQuery.getDepotId())){//查询同步的ERP商品信息
            return getErpGoodsListOfPage(page,productStockQuery);
        }
        return baseMapper.selectOfPage(page,productStockQuery);
    }

    @Override
    public Map<String,Object> totalQuantityAndAmount(ProductStockQuery productStockQuery){
        return baseMapper.totalQuantityAndAmount(productStockQuery);
    }

    public IPage<ProductStockListVo> getErpGoodsListOfPage(Page page,ProductStockQuery productStockQuery) {
        //同步相关搜索条件
        ErpGoodsQuery erpGoodsQuery = new ErpGoodsQuery();
        BeanUtils.copyProperties(productStockQuery,erpGoodsQuery);
        erpGoodsQuery.setGoodsFrom(1);//来源ERP  值1
        erpGoodsQuery.setPage(page);
        //查询同步的ERP商品信息
        Result<MPage<ErpProductVo>> listResult =itemFeign.getErpGoodsList(erpGoodsQuery);

        if(listResult.isSuccess() && ObjectUtil.isNotEmpty(listResult.getData()) && listResult.getData().getRecords().size() > 0){
            //转换返回参数对象
            Page returnPage = new Page();
            List<ProductStockListVo> pslvl = Lists.newArrayList();
            List<ErpProductVo> epvl = listResult.getData().getRecords();
            for (ErpProductVo epv:epvl) {
                ProductStockListVo pslv = new ProductStockListVo();
                BeanUtils.copyProperties(epv,pslv);
                if(ObjectUtil.isNotEmpty(epv.getMarketPrice())){
                    pslv.setMarketPrice(epv.getMarketPrice().toString());
                }
                if(ObjectUtil.isNotEmpty(epv.getDiscountPrice())){
                    pslv.setDiscountPrice(epv.getDiscountPrice().toString());
                }
                if(ObjectUtil.isNotEmpty(epv.getCostPrice())){
                    pslv.setDepotPrice(epv.getCostPrice().toString());
                }
                if(ObjectUtil.isNotEmpty(epv.getMarketPrice()) && ObjectUtil.isNotEmpty(epv.getStock())){
                    pslv.setMarketPriceTotal(new BigDecimal(pslv.getMarketPrice()).multiply(new BigDecimal(pslv.getStock())).toString());
                }
                pslv.setDepotId(productStockQuery.getDepotId());
                pslv.setDepotName(GlobalConstant.DepotCode.ERP);
                pslvl.add(pslv);
            }
            returnPage.setRecords(pslvl);
            returnPage.setPages(listResult.getData().getPages());
            returnPage.setCurrent(listResult.getData().getCurrent());
            returnPage.setSize(listResult.getData().getSize());
            returnPage.setTotal(listResult.getData().getTotal());
            return returnPage;
        }
        return new Page();
    }


    @Override
    public ProductStockVo selectProductStock(ProductStockExistQuery productStockExistQuery) {
        return baseMapper.selectProductStock(productStockExistQuery);
    }

    @Override
    public Integer getByGoodsInfo(Long depotId, Long goodsId, Long productId) {
        System.out.println(depotId+"--"+goodsId+"--"+productId);
        List<ProductStockListVo> list=Lists.newLinkedList();
        ProductStockQuery query=new ProductStockQuery();
        query.setDepotId(depotId);
        query.setGoodsId(goodsId);
        query.setProductId(productId);
        list = productStockDetailsService.selectList(query);
        if(ObjectUtil.isNull(list)){
            return 0;
        }else {
            return list.size();
        }
    }

    @Override
    public List<ProductStockVo> getAllByDepotId(Long depotId) {
        return baseMapper.getAllByDepotId(depotId);
    }

    @Override
    public List<ProductStockVo> getAllAvaByDepotId(Long depotId) {
        return baseMapper.getAllAvaByDepotId(depotId);
    }

    @Override
    @Deprecated
    public void saveInitList(List<ProductStockDto> productStockDtoList, Long uid) {
        List<ProductStock> lists= Lists.newArrayList();
           for(ProductStockDto productStockDto1:productStockDtoList){
               ProductStock entity=new ProductStock();
               ProductStock stock=  baseMapper.findProductStock(productStockDto1.getProductId(),productStockDto1.getStorehouse(),productStockDto1.getStockSn());
               if(null==stock){
                   BeanUtils.copyProperties(stock,entity);
                   entity.setEnableStock(entity.getStock());
               }else{
                   stock.setStock(stock.getStock()+productStockDto1.getStock());
                   stock.setEnableStock(stock.getEnableStock()+productStockDto1.getStock());
                   BeanUtils.copyProperties(stock,entity);
               }
               lists.add(entity);
           }
           saveBatch(lists, ListUtil.SIZE);
    }

    @Override
    public List<ProductStockListVo> selectList(ProductStockQuery productStockQuery) {
        return baseMapper.selectOfPage(productStockQuery);
    }

    @Override
    public void inStock(Long depotId, Long[] productIds) {
        //初始化入库单
     Long  transIn= initInStock(depotId,productIds);
      //根据id 获取商品信息

    }

    @Override
    public void inOutStock(Long depotId, Long productId, int flag,Long uid,String stockSn) {
        OutDepotBillDto outDepotBillDto=new OutDepotBillDto();
        if(flag==2){//出库查询仓库信息
            outDepotBillDto.setOutputDepot(depotId);
            outDepotBillDto.setBillSn(outDepotBillService.getOutBillSn(SnCodeEnum.OUTBILLSN.getValue()));
            outDepotBillDto.setIsFinish(WhetherEnum.YES);
            outDepotBillDto.setOutDepotType(DepotTypeEunm.TYPE_6);
            ProductStockQuery query=new ProductStockQuery();
            query.setProductId(productId);
            query.setDepotId(depotId);
            query.setStockSn(stockSn);
            List<ProductStockListVo> stockDetailsList=productStockDetailsService.selectList(query);
            ProductStockListVo stock=new ProductStockListVo();
            if(ObjectUtil.isNotNull(stockDetailsList)&&stockDetailsList.size()!=0){
                int falg=0;
                for(ProductStockListVo vo:stockDetailsList){
                    if(ObjectUtil.isNotNull(vo.getStockSn())){
                        if(vo.getStockSn().equals(stockSn)){
                            falg=1;
                            stock=vo;
                            break;
                        }
                    }

                }
                if(falg==0){
                    stock=stockDetailsList.get(0);
                }
                List<OutDepotBillProductDto> productDtoList=Lists.newArrayList();
                OutDepotBillProductDto productDto=new OutDepotBillProductDto();
                productDto.setStyleNo(stock.getStyleNo());
                productDto.setSpec(stock.getProductSkuDesp());
                productDto.setProductId(productId);
                GoodsDetailsVo  goodsDetailsVo= goodsFeign.selectGoodsDetails(stock.getGoodsId()).getData();
                if(ObjectUtil.isNotNull(goodsDetailsVo)){
                    productDto.setGoodsName(goodsDetailsVo.getGoodsName());
                    productDto.setGoodsSn(goodsDetailsVo.getGoodsSn());
                }
                productDto.setQuantity(1);
                productDto.setGoodsId(stock.getGoodsId());
                productDto.setProductSn(stock.getProductSn());
                productDto.setStockId(stock.getId());
                productDtoList.add(productDto);
                outDepotBillDto.setProducts(productDtoList);
                outDepotBillService.saveAndAuit(outDepotBillDto,uid);
           }

        }else if(flag==1){//入库操作
            InDepotBillDto  dto=new InDepotBillDto();
            dto.setInputDepot(depotId);
            dto.setInDepotType(DepotTypeEunm.TYPE_6);
            dto.setBillSn(inDepotBillService.getInBillSn(SnCodeEnum.INBILLSN.getValue()));
            dto.setIsFinish(WhetherEnum.YES);
            List<InDepotBillProductDto> products=Lists.newArrayList();
            InDepotBillProductDto dtoList=new InDepotBillProductDto();
            ItemVo itemVo=itemFeign.findById(productId).getData();
            dtoList.setProductSn(itemVo.getProductSn());
            dtoList.setGoodsSn(itemVo.getGoodsSn());
            dtoList.setSpec(itemVo.getProductSkuDesp());
            dtoList.setStyleNo(itemVo.getStyleNo());
            dtoList.setQuantity(1);
            dtoList.setProductId(itemVo.getProductId());
            dtoList.setInDepotId(depotId);
            dtoList.setGoodsName(itemVo.getProductName());
            dtoList.setGoodsId(itemVo.getGoodsId());
            dtoList.setProductName(itemVo.getProductName());
            dtoList.setMarketPrice(itemVo.getMarketPrice());
            dtoList.setStockPrice(itemVo.getCostPrice());

            products.add(dtoList);
            dto.setProducts(products);
            inDepotBillService.saveAndAudit(dto,uid);
        }

    }

    private Long initInStock(Long depotId, Long[] productIds) {
        return  null;
    }

    @Override
    public void saveList(ProductStockSaveDto productStockSaveDto, Long uid) {

        List<ProductStockDto> productStockDtoList = new ArrayList<>();
        ProductStockDto productStockDto = new ProductStockDto();

        //单据id
        Long id = productStockSaveDto.getId();
        //调货单
        if(productStockSaveDto.getStockType()==1){
            //根据调货单id查调货单及其关联商品
            //查到调货单
            GoodsTransBillListVo goodsTransBillListVo = goodsTransBillMapper.getGoodsTransBillById(id);
            //查到调货单关联商品
            List<GoodsTransBillProductVo> GoodsTransBillProductVoList= goodsTransBillProductMapper.getGoodsTransBillProductByGoodsTransId(id,goodsTransBillListVo.getOutputDepot(),null);
            if(GoodsTransBillProductVoList.size()>0){
                List<ProductStockDto> productStockDtoList2 = new ArrayList<>();
                ProductStockDto productStockDto2 = new ProductStockDto();
                //调货入库
                for(int i = 0; i < GoodsTransBillProductVoList.size(); i++){
                    GoodsTransBillProductVo goodsTransBillProductVo = GoodsTransBillProductVoList.get(i);
                    //组织库存对象
                    //调货入库
                    productStockDto.setDepotId(goodsTransBillListVo.getInputDepot());
                    //商品id
                    productStockDto.setGoodsId(goodsTransBillProductVo.getGoodsId());
                    //货品id
                    productStockDto.setProductId(goodsTransBillProductVo.getProductId());
                    //入库数量
                    productStockDto.setStock(goodsTransBillProductVo.getQuantity());
                    //库位
                    productStockDto.setStorehouse(goodsTransBillProductVo.getStorehouse());
                    //添加库存对象list
                    productStockDtoList.add(productStockDto);
                }
                //调货出库
                for(int i = 0; i < GoodsTransBillProductVoList.size(); i++){
                    GoodsTransBillProductVo goodsTransBillProductVo = GoodsTransBillProductVoList.get(i);
                    //组织库存对象
                    //调货出库
                    productStockDto2.setDepotId(goodsTransBillListVo.getInputDepot());
                    //商品id
                    productStockDto2.setGoodsId(goodsTransBillProductVo.getGoodsId());
                    //货品id
                    productStockDto2.setProductId(goodsTransBillProductVo.getProductId());
                    //出库数量（负数）
                    productStockDto2.setStock(0 - goodsTransBillProductVo.getQuantity());
                    //库位
                    productStockDto2.setStorehouse(goodsTransBillProductVo.getStorehouse());
                    //添加库存对象list
                    productStockDtoList2.add(productStockDto);
                }
                //TODO 二期库存逻辑进行了变更
                saveInListUtil(productStockDtoList,uid);
                saveOutListUtil(productStockDtoList2,uid);
            }
        }else if(productStockSaveDto.getStockType()==2){
            //入库单
            //根据入库单id查入库单及其关联商品
            //查到入库单
            InDepotBillVo inDepotBillVo = inDepotBillMapper.getInDepotBillById(id);
            //查到入库单关联商品
            List<InDepotBillProductVo> inDepotBillProductVoList= inDepotBillProductMapper.getInDepotBillProductByInDeoptId(id);
            if(inDepotBillProductVoList.size()>0) {
                //入库
                for (int i = 0; i < inDepotBillProductVoList.size(); i++) {
                    InDepotBillProductVo inDepotBillProductVo = inDepotBillProductVoList.get(i);
                    //组织库存对象
                    //入库仓库id
                    productStockDto.setDepotId(inDepotBillVo.getInputDepot());
                    //商品id
                    productStockDto.setGoodsId(inDepotBillProductVo.getGoodsId());
                    //货品id
                    productStockDto.setProductId(inDepotBillProductVo.getProductId());
                    //入库数量
                    productStockDto.setStock(inDepotBillProductVo.getQuantity());
                    //库位
                    productStockDto.setStorehouse(inDepotBillProductVo.getStorehouse());
                    //添加库存对象list
                    productStockDtoList.add(productStockDto);
                }
                //二期库存逻辑进行了变更
                saveInListUtil(productStockDtoList,uid);
            }

        }else {
            //出库单
            //根据出库单id查出库单及其关联商品
            //查到出库单
            OutDepotBillVo outDepotBillVo = outDepotBillMapper.getOutDepotBillById(id);
            //查到出库单关联商品
            List<OutDepotBillProductVo> outDepotBillProductVoList= outDepotBillProductMapper.getOutDepotBillProductByOutDeoptId(id);
            if(outDepotBillProductVoList.size()>0) {
                //chu库
                for (int i = 0; i < outDepotBillProductVoList.size(); i++) {
                    OutDepotBillProductVo outDepotBillProductVo = outDepotBillProductVoList.get(i);
                    //组织库存对象
                    //出库仓库id
                    productStockDto.setDepotId(outDepotBillVo.getOutputDepot());
                    //商品id
                    productStockDto.setGoodsId(outDepotBillProductVo.getGoodsId());
                    //货品id
                    productStockDto.setProductId(outDepotBillProductVo.getProductId());
                    //出库数量
                    productStockDto.setStock(0 - outDepotBillProductVo.getQuantity());
                    //库位
                    productStockDto.setStorehouse(outDepotBillProductVo.getStorehouse());
                    //添加库存对象list
                    productStockDtoList.add(productStockDto);
                }
                //二期库存逻辑进行了变更
                saveOutListUtil(productStockDtoList,uid);
            }

        }
    }

    /**
     * 入库操作
     * @param productStockDtoList
     * @param uid
     */
    private void saveInListUtil(List<ProductStockDto> productStockDtoList, Long uid) {
    }

    /**
     * 出库操作
     * @param productStockDtoList
     * @param uid
     */
    private void saveOutListUtil(List<ProductStockDto> productStockDtoList, Long uid) {

    }


    /**
     * @Description 库存  入库/出库 <br/>
     * @author gjq
     * @date 2019/12/10 18:18
     * @param productStockDtoList
     * @return void
     */
    public void saveListUtil(List<ProductStockDto> productStockDtoList,Long uid) {
        for(int i=0;i<productStockDtoList.size();i++){
            //单个库存对象
            ProductStockDto productStockDto= productStockDtoList.get(i);

            //组织查询
            ProductStockExistQuery productStockExistQuery = new ProductStockExistQuery();
            //仓库id
            productStockExistQuery.setDepotId(productStockDto.getDepotId());
            //商品id
            productStockExistQuery.setGoodsId(productStockDto.getGoodsId());
            //货品id
            productStockExistQuery.setProductId(productStockDto.getProductId());
         /*   //如果存在库位就做为查询条件
            if(productStockDto.getStorehouse() != null){
                productStockExistQuery.setStorehouse(productStockDto.getStorehouse());
            }*/
            ProductStockVo productStockVo = baseMapper.selectProductStock(productStockExistQuery);

            ProductStock productStock = new ProductStock();
            if(productStockVo == null){
                BeanUtils.copyProperties(productStockDto,productStock);
                if(productStock.getStock().intValue()<0){
                    throw new BusinessException("库存不允许小于0");
                }
                productStock.setCreatedBy(uid);
                save(productStock);
            }else{
                //原表库存
                int stock = productStockVo.getStock();
                //原表可用库存
                int enableStock = productStockVo.getEnableStock();
                //计算后的库存(原表库存加上入库/出库数量)(入库数量为正，出库数量为负数)
                int stockAfter = stock + productStockDto.getStock();
                //计算后的可用库存(原表可用库存减去入库/出库数量)(入库数量为正，出库数量为负数)
                int enableStockAfter = enableStock - productStockDto.getStock();
                productStockDto.setStock(stockAfter);
                productStockDto.setEnableStock(enableStockAfter);
                BeanUtils.copyProperties(productStockDto,productStock);
                productStock.setUpdatedBy(uid);
                productStock.setUpdatedTime(new Date());
                //修改库存
                if(productStock.getStock().intValue()<0){
                    throw new BusinessException("库存不允许小于0");
                }
                updateById(productStock);
            }
        }
    }

    /**
     * 执行逻辑
     * @param list
     */
    @Override
    public void syncErpProductStock(List<RpcProductStockDto> list) {
          List<ProductStock> saveList = Lists.newArrayList();
          for (RpcProductStockDto r:list){
              ProductStock ps=new ProductStock();
              BeanUtils.copyProperties(r,ps);
              saveList.add(ps);
          }
          if(saveList.size()>0){
              saveBatch(saveList,ListUtil.SIZE);
          }
    }

    /**
     * ERP同步 先删除所有原数据
     * @param depotId
     */
    @Override
    public void delSyncErpData(Long depotId){
        if(depotId != null){
            remove(new LambdaQueryWrapper<ProductStock>().eq(ProductStock::getDepotId,depotId));
        }
    }
}
